﻿using Abp.Application.Services;
using Abp.Domain.Uow;
using GN.Pay.Application.Dto.Input;
using GN.Pay.Application.Dto.Output;
using GN.Pay.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace GN.Pay.Application
{
    /// <summary>
    /// 支付应用服务抽象
    /// </summary>
    public abstract class APayAppService : ApplicationService, IPayAppService
    {
        protected APayAppService()
        {
            LocalizationSourceName = Consts.LocalizationSourceName;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="IsTransactional"></param>
        /// <returns></returns>
        private UnitOfWorkOptions CreateOptions(bool isTransactional,
            System.Transactions.IsolationLevel? isolationLevel,
            TransactionScopeOption? scope, TimeSpan? timeout)
        {
            return new UnitOfWorkOptions
            {
                IsTransactional = isTransactional,
                IsolationLevel = isolationLevel,
                Timeout = timeout,
                Scope = scope
            };
        }

        /// <summary>
        /// 创建查询工作单元选项
        /// </summary>
        /// <returns></returns>
        protected UnitOfWorkOptions CreateQueryUnitOfWorkOptions()
        {
            return CreateOptions(false, null, null, null);
        }

        /// <summary>
        /// 创建更新工作单元选项
        /// </summary>
        /// <returns></returns>
        protected UnitOfWorkOptions CreateUpdateUnitOfWorkOptions()
        {
            return CreateOptions(true, System.Transactions.IsolationLevel.RepeatableRead,
                            TransactionScopeOption.RequiresNew, new TimeSpan(0, 0, 180));
        }

        /// <summary>
        /// 查询工作单元
        /// </summary>
        /// <param name="fun">活动</param>
        protected async Task QueryUnitOfWorkAsync(Action action)
        {
            var options = CreateQueryUnitOfWorkOptions();
            using (var uow = UnitOfWorkManager.Begin(options))
            {
                action();
                await uow.CompleteAsync();
            }
        }

        /// <summary>
        /// 查询工作单元
        /// </summary>
        /// <param name="action">活动</param>
        protected void QueryUnitOfWork(Action action)
        {
            var options = CreateQueryUnitOfWorkOptions();
            using (var uow = UnitOfWorkManager.Begin(options))
            {
                action();
                uow.Complete();
            }
        }

        /// <summary>
        /// 更新工作单元
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="action"></param>
        /// <returns></returns>
        protected async Task UpdateUnitOfWorkAsync(Action action)
        {
            var options = CreateUpdateUnitOfWorkOptions();
            using (var uow = UnitOfWorkManager.Begin(options))
            {
                action();
                await uow.CompleteAsync();
            }
        }

        /// <summary>
        /// 更新工作单元
        /// </summary>
        /// <param name="action">活动</param>
        protected void UpdateUnitOfWork(Action action)
        {
            var options = CreateUpdateUnitOfWorkOptions();
            using (var uow = UnitOfWorkManager.Begin(options))
            {
                action();
                uow.Complete();
            }
        }

    }
}
